Components.utils.import("resource://lucidity/lucidapi.jsm");
Components.utils.import("resource://gre/modules/JSON.jsm");
var lucidctx = new (lucidapi.CryptoOperator.extend(function(classref) { return {
    initialize: function()
    {
        classref.superClass.initialize.call(this,window);
    }
}}));

(function()
{
    /* find a select in a frame */
    function getFrameSelection( selectable )
    {
        var selObj = selectable.getSelection();
        if (selObj && (selObj.toString() != ""))
        {
            return selObj;
        }
        else
        {
            var frames = selectable.frames;
            if (!frames)
                return null;
            for (var ii = 0; ii < frames.length; ++ii)
            {
                selObj = getFrameSelection(frames[ii]);
                if (selObj)
                {
                    return selObj;
                }
            }
        }
        return null;
    }

    /* Return actual selection. */
    function getActiveSelection()
    {
        var selObj = getFrameSelection(getBrowser().contentWindow);
        if (selObj)
        {
            return selObj.toString();
        }
        else
        {
            var focused = document.commandDispatcher.focusedElement;
            if (focused && focused.value)
            {
                return focused.value.substring(focused.selectionStart, focused.selectionEnd);
            }
        }
        return "";
    }

    /*
    * Modify the selection.
    */
    function setActiveSelection( text, siginfo )
    {
        if (lucidapi.config.noInPlaceResults)
            return false;

        var focused = document.commandDispatcher.focusedElement;
        if (!focused)
            return false;

        var startPos = focused.selectionStart;
        var endPos = focused.selectionEnd;
        var origval = focused.value;

        if (origval.substring(startPos, endPos).length < 1)
            return false;

        focused.value = origval.substring(0, startPos) + text + origval.substring(endPos, origval.length);

        focused.selectionStart = startPos;
        focused.selectionEnd = startPos + text.length;

        if (siginfo != null)
        {
            lucidapi.promptAlert(lucidapi.formatSignatureResultMessage(siginfo));
        }
        return true;
    }

    lucidapi.absorb(lucidctx,{

        getInvocationTarget: function()
        {
            var data = getActiveSelection();
//            if (!data)
//            {
//                data = classref.superClass.getInvocationTarget.call(this);
//            }
            return data;
        },

        handleInplaceResult: function( resultobj )
        {
            var stuff = resultobj.m_result;
            var sigdata = resultobj.m_siginfo;
            if (stuff)
            {
                return setActiveSelection(stuff, sigdata);
            }
            else if (sigdata)
            {
                lucidapi.promptAlert(lucidapi.formatSignatureResultMessage(sigdata));
                return true;
            }
            return false;
        }
    });

    lucidctx.openEditor = function()
    {
//        lucidapi.error("foo");
//        lucidapi.debug("foo %d %s", 7, "bang");
//        lucidapi.assert(false);
//        lucidapi.assert(false,"foo %d %s", 8, "bang");
//        lucidapi.error(new Error("ImAnError"));
//        lucidapi.error(new RangeError("ImARangeError"));
//        lucidapi.error(lucidapi.createThrowable("luciderr.test"));
////
//        try {
////            throw new RangeError("ImAnotherRangeError");
//            asldgkjhsdl.asdfglkjasdhglk;
//        } catch (ex) {
//            lucidapi.error(ex);
//        }
////
//        try {
//            throw lucidapi.createThrowable("luciderr.alttest",2);
//        } catch (ex) {
//            lucidapi.error(ex);
//        }

//        dump((new RangeError('foo')).toSource() + "\n");

//        function doEval(val)
//        {
//            dump(val + " : " + eval(val) + "\n");
//        }
//
//        doEval("(new Error('hi')) instanceof Error");
//        doEval("(new RangeError('hi')) instanceof Error");
//        lucidapi.keyLookup("John+Connor");
        this.showEditorWindow(getActiveSelection());
    };

    lucidctx.toggleLucidLog = function()
    {
        var logbox = document.getElementById('lucid-logbox');
        if (!logbox)
            return;
        var logsplitter = document.getElementById('lucid-content-splitter');
        if (logbox.collapsed)
        {
            logsplitter.collapsed = false;
            logbox.collapsed = false;
        }
        else
        {
            logsplitter.collapsed = true;
            logbox.collapsed = true;
        }
    }

    function addLogSourceRow(treechildren,label)
    {
        var logdoc = treechildren.ownerDocument;
        var treeitem2 = logdoc.createElement("treeitem");
        treechildren.appendChild(treeitem2);
        var treerow2 = logdoc.createElement("treerow");
        treeitem2.appendChild(treerow2);
        var treecell2 = logdoc.createElement("treecell");
        treerow2.appendChild(treecell2);
        treecell2.setAttribute("label",label);
        return treeitem2;
    }

    function addStuffToLog(logmsg)
    {
        var treechildren = document.getElementById('lucid-logtreechildren');
        if (!treechildren)
            return;

        var msg = logmsg.message;
        var stack = logmsg.stack;
        var logdoc = treechildren.ownerDocument;
        var treeitem = addLogSourceRow(treechildren,msg);

        var treechildren2 = logdoc.createElement("treechildren");
        treeitem.appendChild(treechildren2);
        treeitem.setAttribute("container","true");

        while (stack)
        {
            addLogSourceRow(treechildren2,stack.filename + ":" + stack.lineNumber);
            stack = stack.caller;
        }
    }


    var apiObserver = new (lucidapi.AbstractClass.extend(function(classref) {

        return {

            initialize: function()
            {
                classref.superClass.initialize.call(this);
            },

            register: function(){
                var observerService = lucidapi.getXpcomService("@mozilla.org/observer-service;1", "nsIObserverService");
                observerService.addObserver(this,"lucid-logmsg",false);
//                observerService.addObserver(this,"lucid-pcache",false);
            },

            unregister: function(){
                var observerService = lucidapi.getXpcomService("@mozilla.org/observer-service;1", "nsIObserverService");
                observerService.removeObserver(this,"lucid-logmsg");
//                observerService.removeObserver(this,"lucid-pcache");
            },

            observe: function(subject,topic,data){
                switch (topic) {
                    case "lucid-logmsg":
                        addStuffToLog(JSON.fromString(data));
                        break;
//                    case "lucid-pcache":
//                        document.getElementById('passcacheemptyBroadcaster').hidden = "cleared" == data ? true : false;
//                        break;
                }
            }

    }}));

    function handleLogtreeClick(event){
      var row = {}, column = {}, part = {};
      var tree = event.currentTarget;

      var boxobject = tree.boxObject;
      boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
      boxobject.getCellAt(event.clientX, event.clientY, row, column, part);

        if (row.value > -1)
        {
            var level = tree.view.getLevel(row.value,column.value);
            if (level > 0)
            {
                var label = tree.view.getCellText(row.value,column.value);
                var colIdx = label.lastIndexOf(":");
                var lineno = parseInt(label.substr(colIdx + 1),10);
                var fileurl = label.substr(0,colIdx);
                lucidapi.openViewSource(fileurl,lineno);
            }
        }
    }

    window.addEventListener("load", function()
    {
        lucidapi.handleLoad( window );
        document.getElementById('lucidity-menu-popup').addEventListener("popupshowing", lucidctx.updateObservers, false);
        document.getElementById('lucidity-context-popup').addEventListener("popupshowing", lucidctx.updateObservers, false);
        var tree = document.getElementById("lucid-logtree");
        if (tree)
            tree.addEventListener("click", handleLogtreeClick, false);
        lucidapi.checkForUpgrade();
        apiObserver.register();
    }, false);

    window.addEventListener("unload", function() {
        apiObserver.unregister();
    }, false );

})();

